﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace pyTivoMetadataManager
{
    public class TheTvDbApi
    {
        public Uri ApiBaseUri = new Uri("http://www.thetvdb.com/api/");
        public Uri ApiKeyedBaseUri = new Uri(string.Format("http://www.thetvdb.com/api/{0}/", KeysSingleton.Instance.TheTvDbApiKey));
        private WebClient client = new WebClient();

        private List<string> xmlMirrors = new List<string>();
        private List<string> bannerMirrors = new List<string>();
        private List<string> zipMirrors = new List<string>();

        Random _random = new Random();

        private Uri _xmlMirror = null;
        private Uri XmlMirror
        {
            get
            {
                if (_xmlMirror == null)
                {
                    _xmlMirror = new Uri(xmlMirrors[_random.Next(xmlMirrors.Count)]);
                }
                return (_xmlMirror);
            }
        }
        private Uri _bannerMirror = null;
        private Uri BannerMirror
        {
            get
            {
                if (_bannerMirror == null)
                {
                    _bannerMirror = new Uri(bannerMirrors[_random.Next(bannerMirrors.Count)]);
                }
                return (_bannerMirror);
            }
        }
        private Uri _zipMirror = null;
        private Uri ZipMirror
        {
            get
            {
                if (_zipMirror == null)
                {
                    _zipMirror = new Uri(zipMirrors[_random.Next(zipMirrors.Count)]);
                }
                return (_zipMirror);
            }
        }

        private long timeStamp;

        public TheTvDbApi()
        {
            InitializeMirrorLists();
            GetServerTime();
        }

        private void InitializeMirrorLists()
        {
            Uri uriMirrors = new Uri(ApiKeyedBaseUri, "mirrors.xml");

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(client.DownloadString(uriMirrors));

            XmlNodeList mNodes = doc.SelectNodes("//Mirror");
            foreach (XmlNode mNode in mNodes)
            {
                TvDbMirrorType mType = (TvDbMirrorType)int.Parse(mNode.SelectSingleNode("typemask").InnerText);
                string mirrorPath = mNode.SelectSingleNode("mirrorpath").InnerText;
                if ((TvDbMirrorType.xml & mType) == TvDbMirrorType.xml)
                {
                    xmlMirrors.Add(mirrorPath);
                }
                if ((TvDbMirrorType.banner & mType) == TvDbMirrorType.banner)
                {
                    xmlMirrors.Add(mirrorPath);
                }
                if ((TvDbMirrorType.zip & mType) == TvDbMirrorType.zip)
                {
                    xmlMirrors.Add(mirrorPath);
                }
            }
        }

        private void GetServerTime()
        {
            Uri uriUpdates = new Uri(ApiKeyedBaseUri, "updates/");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(client.DownloadString(uriUpdates));

            XmlNode dNode = doc.SelectSingleNode("/Data");
            timeStamp = long.Parse(dNode.Attributes["time"].Value);
        }

        private Dictionary<string, TtdSeriesInfo> GetSeries(string name)
        {
            Uri uriSeries = new Uri(ApiBaseUri, "GetSeries.php?seriesname=" + name);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(client.DownloadString(uriSeries));

            XmlNodeList sNodes = doc.SelectNodes("//Series");
            Dictionary<string, TtdSeriesInfo> shows = new Dictionary<string, TtdSeriesInfo>();
            foreach (XmlNode sNode in sNodes)
            {
                TtdSeriesInfo si = new TtdSeriesInfo();
                si.ttdId = sNode.SelectSingleNode("id").InnerText;
                sNode.SelectSingleNodeValueInto("language", ref si.Language);
                sNode.SelectSingleNodeValueInto("SeriesName", ref si.SeriesName);
                sNode.SelectSingleNodeValueInto("Overview", ref si.Overview);
                string sFirstAired = null;
                sNode.SelectSingleNodeValueInto("FirstAired", ref sFirstAired);
                if (!string.IsNullOrEmpty(sFirstAired)) si.FirstAired = DateTime.Parse(sFirstAired);
                sNode.SelectSingleNodeValueInto("zap2it_id", ref si.SeriesId);
                sNode.SelectSingleNodeValueInto("IMDB_ID", ref si.ImdbId);
                sNode.SelectSingleNodeValueInto("banner", ref si.BannerPath);

                shows.Add(si.ttdId, si);
            }
            return (shows);
        }

        private TtdSeriesInfo GetSeriesDetails(string ttdId)
        {
            TtdSeriesInfo seriesInfo = new TtdSeriesInfo();
            Uri uriSeries = new Uri(ApiKeyedBaseUri, string.Format("series/{0}/all", ttdId));

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(client.DownloadString(uriSeries));

            XmlNodeList sNodes = doc.SelectNodes("//Series");
            foreach (XmlNode sNode in sNodes)
            {
            }
            return (seriesInfo);
        }
    }

    [Flags]
    public enum TvDbMirrorType
    {
        xml = 1,
        banner = 2,
        zip = 4
    }

    public class TtdSeriesInfo
    {
        public string ttdId;
        public string Language;
        public string SeriesName;
        public string Overview;
        public DateTime? FirstAired;
        public string SeriesId;
        public string ImdbId;
        public string BannerPath;

        public List<string> Actors = new List<string>();
        public List<string> Genres = new List<string>();
        public string TvRating;
        public string Network;
        public double Rating;
        public Dictionary<int, TtdSeasonInfo> Seasons = new Dictionary<int, TtdSeasonInfo>();
    }

    public class TtdSeasonInfo
    {
        public int Number;
        public Dictionary<int, TtdEpisodeInfo> Episodes = new Dictionary<int,TtdEpisodeInfo>();
    }

    public class TtdEpisodeInfo
    {
        public int Number;
        public string EpisodeName;
        public string Director;
        public List<string> GuestStars = new List<string>();
        public DateTime? FirstAired;
        public string ImbdId;
        public string Language;
        public string Overview;
        public string Writer;
        public double? Rating;
    }
}
